package vr;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Logger;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

public class Results {

	private Vector<Participant> results = new Vector<>();
	private DateTimeFormatter sdf = DateTimeFormat.forPattern("HH:mm");
	//private DateTime dateFirst = new DateTime().plusHours(19).plusMinutes(30);

	private String getFileName(int id) {
		return "result/result_" + id + ".vrxml";
	}

	private void fetchSource(int id) throws MalformedURLException,
			UnsupportedEncodingException, ProtocolException, IOException {
		Reader r = getReader(id);
		InputStream is = new ReaderInputStream(r);
		File file = new File(getFileName(id));
		file.getParentFile().mkdirs();
		FileOutputStream f = new FileOutputStream(file);
		IOUtils.copy(is, f);
		f.close();
	}

	public Vector<Participant> getResults(Startlist sl)
			throws MalformedURLException, UnsupportedEncodingException,
			ProtocolException, IOException {

		for (int i = 0; i < sl.get().size(); i++) {
			Logger.getGlobal().info(
					String.format("Fetching %d out of %d", i + 1, sl.get()
							.size()));
			InputStream is;
			int id = sl.get().get(i);
			if (!Files.exists(Paths.get(getFileName(id)))) {
				fetchSource(sl.get().get(i));
			}

			File file = new File(getFileName(id));
			is = new FileInputStream(file);

			Document doc = Jsoup
					.parse(is, "ISO-8859-1", "", Parser.xmlParser());

			Participant result = new Participant();

			fetchBib(doc, result);
			fetchName(doc, result);
			fetchDelta(doc, result);

			results.add(result);
		}
		return results;
	}

	private void fetchName(Document doc, Participant result) {
		Elements el = doc.select("div.content > h3");
		try {
			result.name = el.first().text();
		} catch (NullPointerException | IndexOutOfBoundsException e) {
			Logger.getGlobal().info(e.getStackTrace().toString());
		}
	}

	private void fetchBib(Document doc, Participant result) {
		Elements el = doc.select("table.participants > tr.race");
		try {
			result.bib = Integer.parseInt(el.get(0).select("td").get(2).text());
		} catch (NullPointerException | IndexOutOfBoundsException e) {
			Logger.getGlobal().info(e.getStackTrace().toString());
		}
	}

	private void fetchDelta(Document doc, Participant result) {
		Elements el = doc.select("table.sub-goals > tr");

		Boolean startOnFriday = false;
		// result.dateStart = getTime(el, 1, "td", 1);
		// if (result.dateStart.getHourOfDay() > 18) {
		// startOnFriday = true;
		// }
		//
		// result.dateGylleneUttern = getTime(el, 2, "td", 1);
		// result.dateBankeryd = getTime(el, 3, "td", 1);
		// result.dateHjo = getTime(el, 4, "td", 1);
		// result.dateAspa = getTime(el, 5, "td", 1);
		// result.dateMedevi = getTime(el, 6, "td", 1);
		// result.dateMotala = getTime(el, 7, "td", 1);

		DateTime dStart = getTime(el, 1, "td", 1);
		if (dStart != null) {
			//dStart = dStart.plusDays(1);
			if (dStart.getHourOfDay() > 18) {
				startOnFriday = true;
			}
		}
		result.timestamp.add(dStart);

		Boolean newDay = false;
		for (int i = 0; i < 7; i++) {
			DateTime d = getTime(el, i+2, "td", 1);
			
			if (d != null && startOnFriday) {
				if (d.getHourOfDay() < 19) {
					newDay = true;
				}

				if (newDay) {
					d = d.plusDays(1);
				}
			}


			result.timestamp.add(d);
		}

//		if (startOnFriday) {
//			for (int i = 1; i <= 7; i++) {
//				DateTime dCurr = result.timestamp.get(i);
//				result.timestamp.
//
//			}
//		}
		// if (startOnFriday) {
		// if (result.dateGylleneUttern.hourOfDay().get() > 18
		// && result.dateGylleneUttern.hourOfDay().get() < 23) {
		// result.dateGylleneUttern = result.dateGylleneUttern
		// .plusDays(-1);
		// }
		// }
		if (startOnFriday) {
		}

		// DateTime start = result.dateStart];
		// DateTime goal = result.dateMotala];
		// System.out.println("Result: " + Hours.hoursBetween(start, goal) + ":"
		// + (Minutes.minutesBetween(start, goal).getMinutes()) % 60);
	}

	private DateTime getTime(Elements el, int i1, String pattern, int i2) {

		DateTime d = null;
		try {
			Element e = el.get(i1).select(pattern).get(i2);
			d = sdf.parseDateTime(e.text());
		} catch (NullPointerException | IndexOutOfBoundsException e) {
			Logger.getGlobal().info(e.getStackTrace().toString());
		}

		return d;
	}

	private Reader getReader(int id) throws MalformedURLException,
			UnsupportedEncodingException, IOException, ProtocolException {
		URL url = new URL(
				"http://vatternrundan.se/wp-admin/admin-ajax.php?lang=sv");
		Map<String, Object> params = new LinkedHashMap<>();

		params.put("action", "getParticipant");
		params.put("pid", id);

		StringBuilder postData = new StringBuilder();
		for (Map.Entry<String, Object> param : params.entrySet()) {
			if (postData.length() != 0)
				postData.append('&');
			postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
			postData.append('=');
			postData.append(URLEncoder.encode(String.valueOf(param.getValue()),
					"UTF-8"));
		}
		byte[] postDataBytes = postData.toString().getBytes("UTF-8");

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Type",
				"application/x-www-form-urlencoded");
		conn.setRequestProperty("Content-Length",
				String.valueOf(postDataBytes.length));
		conn.setDoOutput(true);
		conn.getOutputStream().write(postDataBytes);

		return new BufferedReader(new InputStreamReader(conn.getInputStream(),
				"UTF-8"));
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("<results>");
		for (Participant r : results) {
			if (r.name != null && !r.name.isEmpty()) {
				sb.append(r.toString());
			}

		}
		sb.append("</results>");

		return sb.toString();
	}
}
